package martian.t1me
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.NetStatusEvent;
	import flash.net.NetConnection;
	import flash.net.ObjectEncoding;
	import flash.net.Responder;
	
	import martian.t1me.core.Sequencable;
	import martian.t1me.core.Sequence;
	
	public class Message extends EventDispatcher implements Sequencable
	{
		static public const SUCCESS:String = "remotingEventSuccess";
		static public const FAILURE:String = "remotingEventFailure";
		
		static public var GATEWAY:String = "http://localhost/_amf/gateway.php";
		static public var DEBUG:Boolean = true;
		
		static private var cnx:NetConnection;
		static private var rsp:Responder;
			static private function connect():void
			{
				cnx = new NetConnection();
					cnx.objectEncoding = ObjectEncoding.AMF3;
					cnx.addEventListener(NetStatusEvent.NET_STATUS, status);
					cnx.connect(GATEWAY);
			}
			
			static private function status(e:NetStatusEvent):void { if (DEBUG) { log(e.info.code); } }
		
		
		
		
		
		
		public var method:String;
		public var parameters:Array;
		
		private var rsp:Responder;

		public var store:Boolean = false;

		private var hst:Array;
			public function get history():Array { return hst; }
			
		private var raw:*;
			public function get data():Object { return raw; }
			
		public function Message(method:String, ...parameters)
		{
			if (cnx == null) { connect(); }
			
			this.method = method;
			this.parameters = parameters;
			
			rsp = new Responder(success, failure);
		}
		
		public function send():void { start(); }
		
		public function start():void
		{
			cnx.call(method, rsp, parameters);
			dispatchEvent(new Event(Sequence.START));
		}
		
		private function success(arg:Object):void
		{
			if (store)
			{
				if (hst == null) { hst = new Array(); }
				if (raw != null) { hst.push(raw); }
			}
			
			raw = arg;
			
			dispatchEvent(new Event(SUCCESS));
			dispatchEvent(new Event(Sequence.STOP));
		}
		
		private function failure(arg:Object):void
		{
			raw = arg;
			
			dispatchEvent(new Event(FAILURE));
			dispatchEvent(new Event(Sequence.STOP));
		}
	}
}